package org.c3p0.spring.boot.autoconfigure;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.c3p0.spring.boot.autoconfigure.properties.C3p0DataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/**
 * @author XCH
 * @date 2025/9/15
 */
@Configuration
/**
 * 当ComboPooledDataSource.class存在classpath时则初始化配置类
 */
@ConditionalOnClass(ComboPooledDataSource.class)
/**
 * C3p0DataSourceAutoConfigure配置类会在
 * DataSourceAutoConfiguration之前先加载
 */
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
/**
 * 将带有@ConfigurationProperties注解的类纳入Spring容器中管理，
 * 便于注入使用
 * DataSourceProperties绑定的是spring数据源连接属性
 * C3p0DataSourceProperties绑定是C3P0的连接池属性
 */
@EnableConfigurationProperties({DataSourceProperties.class, C3p0DataSourceProperties.class})
/**
 * springboot在2.2以后提供了@ConfigurationPropertiesScan
 * 注解来扫描@ConfigurationProperties注解的类
 */
//@ConfigurationPropertiesScan("org.c3p0.spring.boot.autoconfigure.properties")
public class C3p0DataSourceAutoConfigure {

    /**
     * 注入绑定的数据源属性，用于装配DataSource
     */
    @Autowired
    private C3p0DataSourceProperties c3p0Properties;

    @Autowired
    private DataSourceProperties dataSourceProperties;

    @Bean
    /**
     * 如果spring容器中不存在这个DataSource
     * 的Bean则初始化
     */
    @ConditionalOnMissingBean
    public DataSource dataSource() throws Exception {
        //初始化C3p0的连接池
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        if (dataSourceProperties.getDriverClassName() != null) {
            dataSource.setDriverClass(dataSourceProperties.getDriverClassName());
        }
        if (dataSourceProperties.getUrl() != null) {
            dataSource.setJdbcUrl(dataSourceProperties.getUrl());
        }
        if (dataSourceProperties.getUsername() != null) {
            dataSource.setUser(dataSourceProperties.getUsername());
        }
        if (dataSourceProperties.getPassword() != null) {
            dataSource.setPassword(dataSourceProperties.getPassword());
        }
        dataSource.setMaxPoolSize(c3p0Properties.getMaxPoolSize());
        dataSource.setMinPoolSize(c3p0Properties.getMinPoolSize());
        dataSource.setInitialPoolSize(c3p0Properties.getInitialPoolSize());
        dataSource.setMaxIdleTime(c3p0Properties.getMaxIdleTime());
        System.out.println(dataSource.getConnection());
        return dataSource;
    }
}